<!DOCTYPE html>
<!-- saved from url=(0127)https://docs.google.com/document/d/e/2PACX-1vQ_CnrE4rP_YQfUEdWohrjaWztsU52iiZdgEBoNAflkhbw9tIVDWUZ9xUZsjBGacYTU3aSo_UHx6mXk/pub -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>WebPerfWG call - October 14 2021</title><link rel="shortcut icon" href="https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico"><meta name="referrer" content="strict-origin-when-cross-origin"><style type="text/css" nonce="">
      @import url("https://fonts.googleapis.com/css?family=Google+Sans");
      @import url("https://fonts.googleapis.com/css?family=Roboto");

      body {
        font-family: Roboto, arial, sans, sans-serif;
        margin: 0;
      }

      iframe {
        border: 0;
        frameborder: 0;
        height: 100%;
        width: 100%;
      }

      #banners {
        align-items: center;
        background: white;
        display: block;
        justify-content: space-between;
        position: fixed;
        top: 0;
        width: 100%;
        z-index: 100;
      }

      #banners #publish-banner {
        background-color: #e8f0fe;
        border-bottom: 1px #ccc solid;
        color: #202124;
        display: flex;
        flex: 1 1 0%;
        height: 60px;
        width: 100%;
      }

      #publish-banner-icon {
        display: flex;
        fill: #1967d2;
        margin: auto 20px;
      }

      #publish-banner-text {
        flex-grow: 1;
        margin: auto 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      #publish-banner-buttons {
        margin: auto 25px auto 0;
      }

      #publish-banner-buttons span {
        align-self: center;
        background-color: inherit;
        border: none;
        font-family: "Google Sans", Roboto, RobotoDraft, Helvetica, Arial, sans-serif;
        margin: 0 16px 0 32px;
      }

      #publish-banner-buttons a {
        color: #1967d2;
        cursor: pointer;
        font-family: "Google Sans", Roboto, RobotoDraft, Helvetica, Arial, sans-serif;
        font-size: 14px;
        font-weight: 500;
        line-height: 24px;
        text-decoration: none;
      }

      #banners #title-banner {
        background: white;
        border-bottom: 1px #ccc solid;
        display: flex;
        flex: 1 1 0%;
        height: 60px;
        width: 100%;
      }

      #banners #title-banner #title {
        flex-grow: 1;
        font-family: 'Google Sans';
        font-size: large;
        margin: auto 0 auto 20px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 70%;
      }

      #banners #title-banner #interval {
        margin: auto 25px auto 0;
        font-family: Roboto;
        font-size: small;;
      }

      #footer {
        background: #f0f0f0;
        border-bottom: 1px #ccc solid;
        bottom: 0;
        font-family: Roboto;
        font-size: small;
        padding: 10px 10px;
        position: fixed;
        text-align: center;
        width: 100%;
      }

      #contents {
        padding: 100px 20% 50px 20%;
      }

      @media only screen and (max-device-width: 800px) {
        #banners #title-banner {
          border-bottom-width: 5px;
          height: auto;
          display: block;
        }

        #banners #title-banner #title {
          font-size: 3em;
          margin: auto 0 auto 20px;
          width: 90%;
        }

        #banners #title-banner #interval {
          font-size: 1.5em;
          margin: 10px 0 auto 25px;
        }

        #contents {
          padding: 150px 5% 80px;
        }

        #footer {
          font-size: 2em;
        }
      }

      .dash {
        padding: 0 6px;
      }
    </style></head><body><div id="banners"><div style="display:none" id="publish-banner"><span id="publish-banner-icon"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"></path></svg></span><div id="publish-banner-text">Published using Google Docs</div><div id="publish-banner-buttons"><span><a target="_blank" title="Learn more" href="https://support.google.com/docs/answer/183965">Learn More</a></span><span><a href="https://docs.google.com/u/0/abuse?id=AKkXjoxxSje5tUdaI-ZL5BCNcec8c8NqFABpT-IVDyo8HGwwge1_GWWAts6e7r_yqXx3iApE8wCM3cxKdCPzsao:0"></a></span></div></div><div id="title-banner"><div id="title">WebPerfWG call - October 14 2021</div><div id="interval"><span></span></div></div></div><div id="contents"><style type="text/css">ul.lst-kix_pjha8t17gw3d-3{list-style-type:none}ul.lst-kix_pjha8t17gw3d-4{list-style-type:none}ul.lst-kix_pjha8t17gw3d-5{list-style-type:none}.lst-kix_txwrl4wlurbb-8>li:before{content:"\0025a0  "}.lst-kix_pjha8t17gw3d-3>li:before{content:"\0025cf  "}ul.lst-kix_pjha8t17gw3d-6{list-style-type:none}.lst-kix_pjha8t17gw3d-1>li:before{content:"\0025cb  "}ul.lst-kix_pjha8t17gw3d-7{list-style-type:none}ul.lst-kix_pjha8t17gw3d-8{list-style-type:none}.lst-kix_pjha8t17gw3d-0>li:before{content:"\0025cf  "}.lst-kix_pjha8t17gw3d-4>li:before{content:"\0025cb  "}ul.lst-kix_txwrl4wlurbb-0{list-style-type:none}ul.lst-kix_txwrl4wlurbb-1{list-style-type:none}ul.lst-kix_txwrl4wlurbb-2{list-style-type:none}ul.lst-kix_txwrl4wlurbb-3{list-style-type:none}ul.lst-kix_txwrl4wlurbb-4{list-style-type:none}ul.lst-kix_txwrl4wlurbb-5{list-style-type:none}ul.lst-kix_pjha8t17gw3d-0{list-style-type:none}ul.lst-kix_txwrl4wlurbb-6{list-style-type:none}ul.lst-kix_pjha8t17gw3d-1{list-style-type:none}.lst-kix_pjha8t17gw3d-2>li:before{content:"\0025a0  "}ul.lst-kix_txwrl4wlurbb-7{list-style-type:none}ul.lst-kix_pjha8t17gw3d-2{list-style-type:none}ul.lst-kix_txwrl4wlurbb-8{list-style-type:none}.lst-kix_txwrl4wlurbb-0>li:before{content:"\0025cf  "}.lst-kix_txwrl4wlurbb-1>li:before{content:"\0025cb  "}.lst-kix_pjha8t17gw3d-8>li:before{content:"\0025a0  "}.lst-kix_pjha8t17gw3d-5>li:before{content:"\0025a0  "}.lst-kix_pjha8t17gw3d-7>li:before{content:"\0025cb  "}li.li-bullet-0:before{margin-left:-18pt;white-space:nowrap;display:inline-block;min-width:18pt}.lst-kix_txwrl4wlurbb-7>li:before{content:"\0025cb  "}.lst-kix_pjha8t17gw3d-6>li:before{content:"\0025cf  "}.lst-kix_txwrl4wlurbb-6>li:before{content:"\0025cf  "}.lst-kix_txwrl4wlurbb-5>li:before{content:"\0025a0  "}.lst-kix_txwrl4wlurbb-2>li:before{content:"\0025a0  "}.lst-kix_txwrl4wlurbb-4>li:before{content:"\0025cb  "}.lst-kix_txwrl4wlurbb-3>li:before{content:"\0025cf  "}ol{margin:0;padding:0}table td,table th{padding:0}.c0{margin-left:72pt;padding-top:0pt;padding-left:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c4{margin-left:36pt;padding-top:0pt;padding-left:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c6{margin-left:36pt;padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left;height:11pt}.c5{margin-left:108pt;padding-top:0pt;padding-left:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c8{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:16pt;font-family:"Arial";font-style:normal}.c2{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c1{padding-top:18pt;padding-bottom:6pt;line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c11{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:italic}.c12{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left;height:11pt}.c13{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c9{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.c10{background-color:#ffffff;max-width:468pt;padding:72pt 72pt 72pt 72pt}.c7{color:inherit;text-decoration:inherit}.c3{padding:0;margin:0}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:20pt;color:#000000;font-size:20pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:18pt;color:#000000;font-size:16pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style><div class="c10"><h2 class="c1" id="h.e23m4pvtsxa5"><span class="c8">Participants</span></h2><p class="c12"><span class="c2"></span></p><p class="c13"><span class="c2">Patrick Meenan, Alex Christensen, Giacomo Zecchini, Nicol&aacute;s Pe&ntilde;a Moreno, Noam Rosenthal, Annie Sullivan, Benjamin De Kosnik, Ian Clelland, Corentin Pescheloche, Steven Bougon, Carine, Yoav Weiss, Nic Jansma, Cliff Crocker</span></p><p class="c12"><span class="c2"></span></p><h2 class="c1" id="h.d7meu48gc2ds"><span class="c8">Next Meeting</span></h2><ul class="c3 lst-kix_txwrl4wlurbb-0 start"><li class="c4 li-bullet-0"><span class="c2">TPAC! &nbsp;Oct 25-29</span></li><li class="c4 li-bullet-0"><span class="c2">November 18, 2021</span></li></ul><h2 class="c1" id="h.79e7nz9g3gkf"><span class="c8">Topics</span></h2><ul class="c3 lst-kix_pjha8t17gw3d-0 start"><li class="c4 li-bullet-0"><span class="c2">RT entry’s alignment with Fetch/Response - Noam R</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-1 start"><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Comes from work with ResourceTiming and Fetch integration</span></li><li class="c0 li-bullet-0"><span class="c2">… Found inconsistencies</span></li><li class="c0 li-bullet-0"><span class="c2">… Are resources, fetches and responses the same?</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b><b></b>: inline-block;<b> margin</b><b></b>: 0.00px 0.00px;<b> border</b><b></b>: 0.00px solid #000000;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b><b></b>: 478.00px;<b> height</b><b></b>: 225.00px;"><img alt="" src="./WebPerfWG call - October 14 2021_files/pasted image 0.png" style="width: 478.00px;<b> height</b><b></b>: 225.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c2">… A resource may have multiple fetches</span></li><li class="c0 li-bullet-0"><span class="c2">… A video may fetch multiple segments with 206 Range requests</span></li><li class="c0 li-bullet-0"><span class="c2">… Currently appears in ResourceTiming as a whole bunch of fetches with different body sizes</span></li><li class="c0 li-bullet-0"><span class="c2">… Same goes for responses, ServiceWorkers can have multiple fetches or respond to many requests from a single resource</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-2 start"><li class="c5 li-bullet-0"><span style="overflow: hidden;<b> display</b><b></b>: inline-block;<b> margin</b><b></b>: 0.00px 0.00px;<b> border</b><b></b>: 0.00px solid #000000;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b><b></b>: 579.00px;<b> height</b><b></b>: 349.00px;"><img alt="" src="./WebPerfWG call - October 14 2021_files/pasted image 0(1).png" style="width: 579.00px;<b> height</b><b></b>: 349.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-1"><li class="c0 li-bullet-0"><span class="c2">… Responses are ephemeral things that get passed around, and requests our resources get them</span></li><li class="c0 li-bullet-0"><span class="c2">… Even without ServiceWorkers, responses in the HTTP Cache.</span></li><li class="c0 li-bullet-0"><span class="c2">… HTTP standard underspecifies this</span></li><li class="c0 li-bullet-0"><span class="c2">… A response could be shared between two fetches before it was finished, and they got transferSize as 0 because one registered it as cached, even though it was fetched from network</span></li><li class="c0 li-bullet-0"><span class="c2">… For video elements, we get a whole bunch of entries that look like video, don’t know they’re part of the same resource except by URL</span></li><li class="c0 li-bullet-0"><span class="c2">… Added some WPT tests to see what happens in some of these scenarios</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b><b></b>: inline-block;<b> margin</b><b></b>: 0.00px 0.00px;<b> border</b><b></b>: 0.00px solid #000000;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b><b></b>: 624.00px;<b> height</b><b></b>: 374.67px;"><img alt="" src="./WebPerfWG call - October 14 2021_files/pasted image 0(2).png" style="width: 624.00px;<b> height</b><b></b>: 374.67px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b><b></b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c2">… Tests redirects in a service worker</span></li><li class="c0 li-bullet-0"><span class="c2">… Chrome, Firefox, Safari have different behaviors</span></li><li class="c0 li-bullet-0"><span class="c2">… People who want to rely on those measurements (in environment with serviceworkers, or HTTP caching) would be utterly confused and would have to write different code for each browser</span></li><li class="c0 li-bullet-0"><span class="c2">… Two main suggestions: One is that ResourceEntry would represent a fetch 1:1, so redirects within the fetch you would not see in final entry</span></li><li class="c0 li-bullet-0"><span class="c2">… Second option is only connection info would be forwarded, but not redirects</span></li><li class="c0 li-bullet-0"><span class="c2">… Logic is if you’re using SW you wouldn’t have connection info yourself from outside, so getting that doesn’t interfere with any other information</span></li><li class="c0 li-bullet-0"><span class="c2">… Could be redirects that come before the SW and could be mixed up with redirects happening in SW</span></li><li class="c0 li-bullet-0"><span><b>Yoav</b><b></b>: Clarify what you mean by redirects in SW?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: URL handled by SW. &nbsp;The SW takes the Fetch event, handles it, and does a respondWith(). &nbsp;That leads to something with a redirect. &nbsp;They both have PT entries and objects. &nbsp;Some browsers mix them differently in the client.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: One thing that stands out is generally 1:1 relationship with Fetch makes sense.</span></li><li class="c0 li-bullet-0"><span class="c2">… Also seems like something that's closest to implemented reality although you've found discrepancies</span></li><li class="c0 li-bullet-0"><span class="c2">… Like for VIDEO, each range request is a different Fetch request -- matches reality</span></li><li class="c0 li-bullet-0"><span class="c2">… The bit that I’m hesitant is that there’s a feature request we’ve talked about - how we’d expose multi-request RT entries and redirects in the future, and this goes against being able to do that</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: I wouldn’t say it goes against that. &nbsp;The redirect response sequences are in the Fetch, properties of the Fetch. &nbsp;They could have their own RT entries (and it goes against that a bit), they’re not a Fetch in themselves though.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: Yeah if we have 1:1 RT:Fetch, then we wouldn’t expose them as a separate entry. &nbsp;Though at the same time I’m not sure there’s a strong use case for multiple RT entries for redirects.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Redirects don’t have to be a resource, they could be a sub-resource</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: We could have a RedirectTimingEntry if we wanted them I guess</span></li><li class="c0 li-bullet-0"><span class="c2">… It would influence the shape of that solution if we went that route.</span></li><li class="c0 li-bullet-0"><span class="c2">… In the context of PRs for defining Preload cache, how would that 1:1 relationship work?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Since Preload is a lot more complicated and needs definition, we can derive from that how RT or timing entries for Preload would look like. &nbsp;Preload is a feature in itself and RT should measure it somehow.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: If we define Preload cache above Fetch, this would still work. &nbsp;Preload would trigger a fetch and second one would be preempted.</span></li><li class="c0 li-bullet-0"><span class="c2">… That’s what happens today for RT entries for Preload</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: All of that is solvable, important to have a definition of it instead of relying on existing implementation decisions</span></li><li class="c0 li-bullet-0"><span class="c2">… Issue open about this</span></li><li class="c0 li-bullet-0"><span class="c9"><a class="c7" href="https://www.google.com/url?q=https://github.com/whatwg/fetch/issues/1208&amp;sa=D&amp;source=editors&amp;ust=1634293489579000&amp;usg=AOvVaw0L52dWmzvvHJrcRhNjw8sz">https://github.com/whatwg/fetch/issues/1208</a></span></li><li class="c0 li-bullet-0"><span class="c2"><b>Nic</b><b></b>: From our RUM point of view, no customer complaints, but maybe beyond their ability to measure. Limited to SW cases.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Also impacts the HTTP cache. E.g. a cached response shows the old connection info</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Nic</b><b></b>: We do see weird data all the time, and it’s hard to know why an attribute is different than expected. Precise definition is good.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: In terms of alignment from other implementers, some implementations would need to change</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: All of them will need to change, differently</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Alex</b><b></b>: I don’t think we’ve arrived at the perfect solution yet, but I’m willing to make changes as long as they don’t affect privacy</span></li><li class="c0 li-bullet-0"><span class="c2">… Sounds like it’s heading in a reasonable direction</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Nicol&aacute;s</b><b></b>: Sounds like this would change the API a lot potentially, in terms of kinds of entries retrieved?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: It will erase timings for things coming from SW and HTTP Cache, if that particular fetch is not the one causing the redirect.</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: It will hide it at the page level, but you can get it from the SW that actually did it, which feels like the right separation</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Nicol&aacute;s</b><b></b>: I had the impression that it would be more breaking, but if it’s just moving them around to other places that makes sense</span></li><li class="c0 li-bullet-0"><span><b>Nic</b><b></b>: </span><span>Is anyone aware of use counters of PerfTimeline in SW</span><span class="c2">?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: Not aware of any stats right now</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-2 start"><li class="c5 li-bullet-0"><span>(followup: there are </span><span class="c9"><a class="c7" href="https://www.google.com/url?q=https://chromestatus.com/metrics/feature/timeline/popularity/2189&amp;sa=D&amp;source=editors&amp;ust=1634293489582000&amp;usg=AOvVaw02i6RkZKK6ijbCpJ8AV82o">Chrome stats on Observer use in workers</a></span><span class="c2">, but not on PerformanceTimeline)</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-1"><li class="c0 li-bullet-0"><span class="c2"><b>Benjamin</b><b></b>: So can you clarify what the end results with HTTP cache are?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: If we go down this result, then a RT entry is a fetch</span></li><li class="c0 li-bullet-0"><span><b>Benjamin</b><b></b>: OK, that makes HTTP cache better, thanks</span></li></ul><p class="c12"><span class="c2"></span></p><ul class="c3 lst-kix_pjha8t17gw3d-0"><li class="c4 li-bullet-0"><span class="c2">Priority Hints and responsive images - Patrick Meenan</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-1 start"><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: We have both lazyload and Priority Hints are making image decisions in the markup</span></li><li class="c0 li-bullet-0"><span class="c2">… Some of the early feedback we have is it’s difficult on responsive sites</span></li><li class="c0 li-bullet-0"><span class="c2">… Depending on the viewport if it’s in the view or not</span></li><li class="c0 li-bullet-0"><span class="c2">… In Preload you can use media queries to toggle whether or not Priority Hints will be applied</span></li><li class="c0 li-bullet-0"><span class="c2">… Lazy load can only be applied to &lt;img&gt; itself</span></li><li class="c0 li-bullet-0"><span class="c2">… Suggestion is to tweak the Picture element so individual sources would have lazyload or importance attribute</span></li><li class="c0 li-bullet-0"><span class="c2">… And if individual source has it, it would override what is on the &lt;img&gt; tag</span></li><li class="c0 li-bullet-0"><span class="c2">… So you could choose to have an overall &lt;picture&gt; image that would lazyload, but &lt;source&gt; could load eager or have different importance or other basis</span></li><li class="c0 li-bullet-0"><span class="c2">… Not perfect since you don't have CSS way of doing this</span></li><li class="c0 li-bullet-0"><span class="c2">… In straight HTML seems like the best place you’ve got to make responsive features available</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Michal</b><b></b>: If you can’t do it from CSS since you need to do it during parsing, but if it’s a responsive problem, dont you have a chicken-and-egg problem</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: &lt;picture&gt; is a bit of a responsive element, so it handles media queries at parse time</span></li><li class="c0 li-bullet-0"><span class="c2">… You can’t make the full decision as in the CSS file</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: Parse time media attributes are not just for responsive images, but also for loading priority of styles, that are not applied if the media attribute mismatches</span></li><li class="c0 li-bullet-0"><span class="c2">… We have the ability in HTML to apply some CSS media condition rules but it all happens before layout is applied, before all CSS from all HEAD is downloaded</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: It’s not breaking in any direction if it’s guessed wrong, as lazyload/important is a priorization thing</span></li><li class="c0 li-bullet-0"><span class="c2">… Want to avoid developers having to decide if they prioritize desktop or mobile, if &lt;picture&gt; is the knob where they can make that tweak or not</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: I would love to see examples of real-life sites where that would look like</span></li><li class="c0 li-bullet-0"><span class="c2">… And examples to lazyload and prioritize in some viewports and not others</span></li><li class="c0 li-bullet-0"><span class="c2">… e.g. image is not visible in viewport in some cases where it’s not others</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: Grid vs. vertical scroll layout too</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: Makes sense, also matches recent change for width and height to be applicable for sources and override ones from &lt;img&gt; to enable responsive images to take up their allotted space ahead of time before layout happens before dimensions are known</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: Worst-case hopefully it’s better than current situation even if it’s not perfect</span></li><li class="c0 li-bullet-0"><span class="c2">… Will start work on documenting it at least, then see about implementing it</span></li></ul><p class="c6"><span class="c2"></span></p><ul class="c3 lst-kix_pjha8t17gw3d-0"><li class="c4 li-bullet-0"><span class="c9"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/navigation-timing/issues/160&amp;sa=D&amp;source=editors&amp;ust=1634293489588000&amp;usg=AOvVaw11W2ZLgcLwPjcq4kzQM-JF">NavigationStart and cross-origin redirects</a></span><span class="c2">&nbsp;- Noam R</span></li></ul><ul class="c3 lst-kix_pjha8t17gw3d-1 start"><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Simple topic but has a big implications I believe</span></li><li class="c0 li-bullet-0"><span class="c2">… Did a very minimal demo to show problem</span></li><li class="c0 li-bullet-0"><span class="c2">… [demo]</span></li><li class="c0 li-bullet-0"><span class="c2">… We are on a page, localhost = domain A</span></li><li class="c0 li-bullet-0"><span class="c2">… I have a form for with a checkbox for subscribing to a newsletter</span></li><li class="c0 li-bullet-0"><span class="c2">… Click on button, some time passes, I’m on domain B, which tells me I’m subscribed to a newsletter from A</span></li><li class="c0 li-bullet-0"><span class="c2">… If I go back and don’t click it, it goes to domain B where I didn’t subscribe to newsletter</span></li><li class="c0 li-bullet-0"><span class="c2">… I have a HTTP post from a form to my own domain, and in my own domain I do something that takes a while if I subscribe to newsletter, then I redirect to a new domain</span></li><li class="c0 li-bullet-0"><span class="c2">… How did domain B find out domain A took longer time to do something</span></li><li class="c0 li-bullet-0"><span class="c2">… Because navigationStart, our epoch / zero time for all timing entries</span></li><li class="c0 li-bullet-0"><span class="c2">… navigationStart starts before unload or wherever you can from beginning</span></li><li class="c0 li-bullet-0"><span class="c2">… Could be cross-origin redirects, doesn’t have to be a third-party in between, could be just two origins</span></li><li class="c0 li-bullet-0"><span class="c2">… Could be click to on SERP and it goes to final domain</span></li><li class="c0 li-bullet-0"><span class="c2">… From final domain you can see a bunch of time passed, know about it from user on your domain</span></li><li class="c0 li-bullet-0"><span class="c2">… Proposal is to put navigationStart to be first redirect in our domain or fetchStart of our current document</span></li><li class="c0 li-bullet-0"><span class="c2">… Other option is to use TAO or other permission approach</span></li><li class="c0 li-bullet-0"><span class="c2">… Problem with headers is we tend to overload meaning on them after we publish them</span></li><li class="c0 li-bullet-0"><span class="c2">… Problematic who gives that header, only the domain who can give permission is the last website</span></li><li class="c0 li-bullet-0"><span class="c2">… We have a mechanism called &lt;a ping&gt; which allows us to send whatever we want to the final domain, how many ever redirects</span></li><li class="c0 li-bullet-0"><span class="c2">… I’m suggesting that as one option for how to grant information</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: On the information leak side of things, is the concern only that the timing information is available, or is it linked to referrer stuff</span></li><li class="c0 li-bullet-0"><span class="c2">… Feels like without referrer information, timing information isn't as useful and maybe it’s a referrer problem</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: I wouldn’t underestimate this timing information to know whether you’re logged in to other sites</span></li><li class="c0 li-bullet-0"><span class="c2">… Problem is bigger when you’re talking about referrers</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: Don’t want to lose track of the user’s full experience</span></li><li class="c0 li-bullet-0"><span class="c2">… First part of that window isn’t the problem of the destination site, the unload and redirects may be part of the timing of the site you’re coming from</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: I think it might make sense to use some sort of Reporting API to get that information back to the refererer site, right now it’s sent to a site that can’t do anything about it</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: Scenario?</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: If you have a search engine going to publisher with a click tracker in between. &nbsp;If click tracking takes a while, the search engine should know about it. &nbsp;</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: Maybe it’s the publisher that put in a click tracker, in which case the publisher should be alerted</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Problem for the user, user should know they’re no longer in search engine and not yet on publisher, something else is taking their time</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Pat</b><b></b>: We don’t want them to be blind where this timing is going</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: I think they should share that information between them, e.g. via &lt;a ping&gt;</span></li><li class="c0 li-bullet-0"><span class="c2">… It’s not up to the browser to give that information to either or both of them</span></li><li class="c0 li-bullet-0"><span class="c2">… User owns that information, not the sites</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Yoav</b><b></b>: Beyond Q about how we gain back information, consensus on the thread that this is information we should stop exposing by default</span></li><li class="c0 li-bullet-0"><span class="c2">… Implications are that every site that starts out with X-O redirect will have their performance metrics moved by the amount it takes to redirect</span></li><li class="c0 li-bullet-0"><span class="c2">… navStart point is also time origin for PT</span></li><li class="c0 li-bullet-0"><span class="c2">… All metrics that RUM providers give will change</span></li><li class="c0 li-bullet-0"><span class="c11"><b>Michal</b><b></b>: Perf Win! &nbsp;One weird trick! Ship it!</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Noam</b><b></b>: Can create interesting scenarios where websites try to game this</span></li><li class="c0 li-bullet-0"><span class="c2">… Slot for this at TPAC, I’m not sure if there’s more to discuss here, I don’t know how to proceed</span></li><li class="c0 li-bullet-0"><span class="c2"><b>Nic</b><b></b>: We have based all of our metrics on navStart, all metrics are keyed on how long navStart was. </span></li><li class="c0 li-bullet-0"><span class="c2">… Some customers noticed that this can be a challenge, so had some customers create their own custom timers, as a way to reduce the noise of the things they can’t affect. </span></li><li class="c0 li-bullet-0"><span class="c2">… So changed their timeOrigin with their custom timers</span></li><li class="c0 li-bullet-0"><span class="c2">… So we have some evidence that it makes sense to remove the navStart from there</span></li><li class="c0 li-bullet-0"><span class="c2">… But concern about changing the baseline of all metrics, as it typically leads to confusion</span></li><li class="c0 li-bullet-0"><span class="c2">… Would create communication challenges.</span></li><li class="c0 li-bullet-0"><span class="c2">… So something to think about a little bit more. Let’s followup at TPAC</span></li><li class="c0 li-bullet-0"><span class="c2">… We generally argue to not change the timing definition</span></li></ul><p class="c12"><span class="c2"></span></p></div></div><script type="text/javascript" nonce="">(function(){/*

 Copyright The Closure Library Authors.
 SPDX-License-Identifier: Apache-2.0
*/
var aa="function"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};
function ca(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");}var da=ca(this);function ea(a,b){if(b)a:{var c=da;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}}var h;
if("function"==typeof Object.setPrototypeOf)h=Object.setPrototypeOf;else{var l;a:{var fa={a:!0},ha={};try{ha.__proto__=fa;l=ha.a;break a}catch(a){}l=!1}h=l?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var ia=h;
function m(a,b){a.prototype=aa(b.prototype);a.prototype.constructor=a;if(ia)ia(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.m=b.prototype}ea("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});var n=this||self;function p(){}function q(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}
function ja(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();d.push.apply(d,arguments);return a.apply(this,d)}}function ka(a,b){function c(){}c.prototype=b.prototype;a.m=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.D=function(d,e,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[e].apply(d,g)}}function r(a){return a};function t(a){t[" "](a);return a}t[" "]=p;function la(a,b,c){return Object.prototype.hasOwnProperty.call(a,b)?a[b]:a[b]=c(b)};function ma(a){return la(a.prototype,"$$generatedClassName",function(){return"Class$obf_"+{valueOf:function(){return++na}}})}var na=1E3;function v(){}v.prototype.s=function(){return this.j||(Object.defineProperties(this,{j:{value:oa=oa+1|0,enumerable:!1}}),this.j)};v.prototype.toString=function(){var a=w(x(pa(this.constructor)))+"@";var b=(this.s()>>>0).toString(16);return a+w(b)};function y(){}m(y,v);y.prototype.h=function(a){this.g=a;if(a instanceof Object)try{a.v=this}catch(b){}};function qa(a){a.g instanceof Error&&(Error.captureStackTrace?Error.captureStackTrace(a.g):a.g.stack=Error().stack)}y.prototype.toString=function(){var a=x(pa(this.constructor)),b=this.l;return null==b?a:w(a)+": "+w(b)};
function ra(a){if(null!=a){var b=a.v;if(null!=b)return b}a instanceof TypeError?(b=new sa,b.l=w(a),qa(b),b.i=a,b.h(new TypeError(b)),a=b):(b=new z,b.l=w(a),qa(b),b.i=a,b.h(Error(b)),a=b);return a};function A(){}m(A,y);function B(){}m(B,A);function z(){}m(z,B);z.prototype.h=function(a){B.prototype.h.call(this,"__noinit__"===this.i?a:this.i)};function sa(){}m(sa,z);var oa=0;function ta(a,b){return"string"==typeof a?a.charCodeAt(b):a.g(b)};function C(){}var ua,va;m(C,v);function wa(){wa=function(){};va=new D;ua=new E};function D(){}m(D,C);D.prototype.toString=function(){return""};function E(){}m(E,C);E.prototype.toString=function(){return"unknown"};function w(a){return null==a?"null":a.toString()}function xa(a){return 65536<=a?w(String.fromCharCode((55296+((a-65536|0)>>10&1023)|0)&65535))+w(String.fromCharCode((56320+((a-65536|0)&1023)|0)&65535)):String.fromCharCode(a&65535)}function ya(a,b){var c=b,d=a.length,e;b=ta(a,(e=c,c=c+1|0,e));var f;if(e=55296<=b&&56319>=b&&c<d)a=f=ta(a,c),e=56320<=a&&57343>=a;var g;e?g=65536+((b&1023)<<10)+(f&1023)|0:g=b;return g};function F(a,b){this.g=a;this.h=b}m(F,v);function x(a){if(0!=a.h){var b="L"+w(ma(a.g))+";";a=a.h;for(var c="",d=0;d<a;d=d+1|0)c=w(c)+"[";return w(c)+w(b)}return ma(a.g)}F.prototype.toString=function(){return"class "+w(x(this))};function pa(a){return la(a.prototype,"$$class/0",function(){return new F(a,0)})};function za(a){var b=a;try{var c;if(c="www.google.com"===Aa(a)){var d=Ba(a)[5];c="/url"===G(d,!0)}if(c){var e=Ca(a,"q");b=e?e:Ca(a,"url")}}catch(f){if(f=ra(f),!(f instanceof A))throw f.g;}return null!=b?b:""};function G(a,b){return null==a?a:b?decodeURI(a):decodeURIComponent(a)};var Da;function Ba(a){H();a=Da.exec(a);for(var b=[],c=0;7>=c;c=c+1|0)a.length<=c||null==a[c]?b.push(null):b.push(a[c]);return b}function Aa(a){a=Ba(a);return G(a[3],!0)}
function Ca(a,b){H();var c=a.indexOf(xa(35));c=0>c?a.length:c;a:{var d=0;for(var e=b.length;0<(d=a.indexOf(b,d))&&d<c;){var f=ya(a,d-1|0);if(38==f||63==f){if((d+e|0)>=a.length)break a;f=ya(a,d+e|0);if(61==f||38==f||35==f)break a}d=d+(e+1)|0}d=-1}if(0>d)return null;e=a.indexOf(xa(38),d);if(0>e||e>c)e=c;d=d+(b.length+1)|0;b=Math.min(a.length,d);a=a.substr(b,Math.min(a.length,Math.max(d,e))-b|0);c=" ";for(b=0;0<=(b=c.indexOf("\\",b));)36==c.charCodeAt(b+1|0)?(d=w(c.substr(0,b|0))+"$",e=b=b+1|0,c=d+w(c.substr(e))):
(d=w(c.substr(0,b|0)),e=b=b+1|0,c=d+w(c.substr(e)));a=a.replace(RegExp("\\+","g"),c);return G(a,!1)}function H(){H=function(){};Da=RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\S\\s]*))?$")};var Ea=Array.prototype.indexOf?function(a,b){return Array.prototype.indexOf.call(a,b,void 0)}:function(a,b){if("string"===typeof a)return"string"!==typeof b||1!=b.length?-1:a.indexOf(b,0);for(var c=0;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};var Fa=/&/g,Ga=/</g,Ha=/>/g,Ia=/"/g,Ja=/'/g,Ka=/\x00/g,La=/[\x00&<>"']/;var I;a:{var Ma=n.navigator;if(Ma){var Na=Ma.userAgent;if(Na){I=Na;break a}}I=""}function J(a){return-1!=I.indexOf(a)};function Oa(a,b,c){for(var d in a)b.call(c,a[d],d,a)};var Pa=J("Trident")||J("MSIE"),Qa=J("Edge")||Pa,Ra=J("Gecko")&&!(-1!=I.toLowerCase().indexOf("webkit")&&!J("Edge"))&&!(J("Trident")||J("MSIE"))&&!J("Edge"),Sa=J("Macintosh");function Ta(a){a&&"function"==typeof a.u&&a.u()};function K(){this.h=this.h;this.g=this.g}K.prototype.h=!1;K.prototype.u=function(){this.h||(this.h=!0,this.j())};K.prototype.j=function(){if(this.g)for(;this.g.length;)this.g.shift()()};var L;function M(a,b){this.i=a===Ua&&b||"";this.j=Va}M.prototype.h=!0;M.prototype.g=function(){return this.i};var Va={},Ua={};function N(a,b){this.i=b===O?a:""}N.prototype.h=!0;N.prototype.g=function(){return this.i.toString()};N.prototype.toString=function(){return this.i.toString()};function P(a){return a instanceof N&&a.constructor===N?a.i:"type_error:SafeUrl"}
var Wa=RegExp('^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-matroska|x-wav|wav|webm)|font/\\w+|image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|video/(?:mpeg|mp4|ogg|webm|quicktime|x-matroska))(?:;\\w+=(?:\\w+|"[\\w;,= ]+"))*$',"i"),Xa=/^data:(.*);base64,[a-z0-9+\/]+=*$/i,Ya=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;function Za(a){if(a instanceof N)return a;a="object"==typeof a&&a.h?a.g():String(a);Ya.test(a)||(a="about:invalid#zClosurez");return new N(a,O)}
var O={},$a=new N("about:invalid#zClosurez",O);var ab={};function Q(a,b,c){this.i=c===ab?a:"";this.h=!0}Q.prototype.g=function(){return this.i.toString()};Q.prototype.toString=function(){return this.i.toString()};function bb(a,b,c,d){a=a instanceof N?a:Za(a);b=b||n;c=c instanceof M?c instanceof M&&c.constructor===M&&c.j===Va?c.i:"type_error:Const":c||"";return void 0!==d?b.open(P(a),c,d):b.open(P(a),c)};function R(a,b){this.type=a;this.target=b;this.i=!1}R.prototype.g=function(){this.i=!0};var cb=function(){if(!n.addEventListener||!Object.defineProperty)return!1;var a=!1,b=Object.defineProperty({},"passive",{get:function(){a=!0}});try{n.addEventListener("test",p,b),n.removeEventListener("test",p,b)}catch(c){}return a}();function S(a){R.call(this,a?a.type:"");this.relatedTarget=this.target=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=0;this.key="";this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.pointerId=0;this.pointerType="";this.h=null;if(a){var b=this.type=a.type,c=a.changedTouches&&a.changedTouches.length?a.changedTouches[0]:null;this.target=a.target||a.srcElement;var d=a.relatedTarget;if(d){if(Ra){a:{try{t(d.nodeName);var e=!0;break a}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
b?d=a.fromElement:"mouseout"==b&&(d=a.toElement);this.relatedTarget=d;c?(this.clientX=void 0!==c.clientX?c.clientX:c.pageX,this.clientY=void 0!==c.clientY?c.clientY:c.pageY,this.screenX=c.screenX||0,this.screenY=c.screenY||0):(this.clientX=void 0!==a.clientX?a.clientX:a.pageX,this.clientY=void 0!==a.clientY?a.clientY:a.pageY,this.screenX=a.screenX||0,this.screenY=a.screenY||0);this.button=a.button;this.key=a.key||"";this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.pointerId=a.pointerId||0;this.pointerType="string"===typeof a.pointerType?a.pointerType:db[a.pointerType]||"";this.state=a.state;this.h=a;a.defaultPrevented&&S.m.g.call(this)}}ka(S,R);var db={2:"touch",3:"pen",4:"mouse"};S.prototype.g=function(){S.m.g.call(this);var a=this.h;a.preventDefault?a.preventDefault():a.returnValue=!1};var T="closure_listenable_"+(1E6*Math.random()|0);var eb=0;function fb(a,b,c,d,e){this.listener=a;this.proxy=null;this.src=b;this.type=c;this.capture=!!d;this.h=e;this.key=++eb;this.g=this.o=!1}function gb(a){a.g=!0;a.listener=null;a.proxy=null;a.src=null;a.h=null};function U(a){this.src=a;this.g={};this.h=0}U.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.g[f];a||(a=this.g[f]=[],this.h++);var g;a:{for(g=0;g<a.length;++g){var k=a[g];if(!k.g&&k.listener==b&&k.capture==!!d&&k.h==e)break a}g=-1}-1<g?(b=a[g],c||(b.o=!1)):(b=new fb(b,this.src,f,!!d,e),b.o=c,a.push(b));return b};var V="closure_lm_"+(1E6*Math.random()|0),hb={},ib=0;function jb(a,b,c,d,e){if(d&&d.once)return kb(a,b,c,d,e);if(Array.isArray(b)){for(var f=0;f<b.length;f++)jb(a,b[f],c,d,e);return null}c=lb(c);return a&&a[T]?a.g(b,c,q(d)?!!d.capture:!!d,e):mb(a,b,c,!1,d,e)}
function mb(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=q(e)?!!e.capture:!!e,k=nb(a);k||(a[V]=k=new U(a));c=k.add(b,c,d,g,f);if(c.proxy)return c;d=ob();c.proxy=d;d.src=a;d.listener=c;if(a.addEventListener)cb||(e=g),void 0===e&&(e=!1),a.addEventListener(b.toString(),d,e);else if(a.attachEvent)a.attachEvent(pb(b.toString()),d);else if(a.addListener&&a.removeListener)a.addListener(d);else throw Error("addEventListener and attachEvent are unavailable.");ib++;return c}
function ob(){function a(c){return b.call(a.src,a.listener,c)}var b=qb;return a}function kb(a,b,c,d,e){if(Array.isArray(b)){for(var f=0;f<b.length;f++)kb(a,b[f],c,d,e);return null}c=lb(c);return a&&a[T]?a.h(b,c,q(d)?!!d.capture:!!d,e):mb(a,b,c,!0,d,e)}
function rb(a){if("number"!==typeof a&&a&&!a.g){var b=a.src;if(b&&b[T])b.i(a);else{var c=a.type,d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent?b.detachEvent(pb(c),d):b.addListener&&b.removeListener&&b.removeListener(d);ib--;if(c=nb(b)){d=a.type;if(d in c.g){var e=c.g[d],f=Ea(e,a),g;(g=0<=f)&&Array.prototype.splice.call(e,f,1);g&&(gb(a),0==c.g[d].length&&(delete c.g[d],c.h--))}0==c.h&&(c.src=null,b[V]=null)}else gb(a)}}}
function pb(a){return a in hb?hb[a]:hb[a]="on"+a}function qb(a,b){if(a.g)a=!0;else{b=new S(b,this);var c=a.listener,d=a.h||a.src;a.o&&rb(a);a=c.call(d,b)}return a}function nb(a){a=a[V];return a instanceof U?a:null}var sb="__closure_events_fn_"+(1E9*Math.random()>>>0);function lb(a){if("function"===typeof a)return a;a[sb]||(a[sb]=function(b){return a.handleEvent(b)});return a[sb]};function W(a){K.call(this);this.l=a;this.i={}}ka(W,K);var tb=[];function ub(a){Oa(a.i,function(b,c){this.i.hasOwnProperty(c)&&rb(b)},a);a.i={}}W.prototype.j=function(){W.m.j.call(this);ub(this)};W.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};function vb(a,b,c,d){b=void 0===b?!1:b;c=void 0===c?!1:c;d=void 0===d?"editors":d;K.call(this);this.i=a||document.body;this.s=!!b;this.A=!!c;this.B=d;this.l=new W(this);a=ja(Ta,this.l);this.h?a():(this.g||(this.g=[]),this.g.push(a));a=this.l;b=this.i;c=this.C;d="click";Array.isArray(d)||(d&&(tb[0]=d.toString()),d=tb);for(var e=0;e<d.length;e++){var f=jb(b,d[e],c||a.handleEvent,!1,a.l||a);if(!f)break;a.i[f.key]=f}}m(vb,K);
vb.prototype.C=function(a){if(!(0!=a.h.button||Sa&&a.ctrlKey||a.i))for(var b=a.target;b&&b!=this.i;){if(b.tagName&&"a"==b.tagName.toLowerCase()){var c=b.getAttribute("href")||b.getAttributeNS("http://www.w3.org/1999/xlink","href"),d=za(c);if(c!=d){a:{b=void 0;try{b=Aa(d)}catch(u){u=ra(u);if(u instanceof A){b=!1;break a}throw u.g;}var e;if(e=null!=b){e=(wa(),va);var f=ua;b=Object.is(e,f)||null==e&&null==f?b.toLocaleLowerCase():b.toLowerCase();e=".google.com"===b.substr(b.length-11|0,11)}b=e}if(!b)if(this.A){c=
za(d);if(Object.is(c,d)||null==c&&null==d)d="//www.google.com/url?q="+w(encodeURIComponent(d)),d=w(d)+"&sa=D";d+="&source="+this.B}else d=this.s?c:d;f=d;b=void 0;d={target:"_blank",noreferrer:!0};c=window;if(f instanceof N)e=f;else{e="undefined"!=typeof f.href?f.href:String(f);if(!(e instanceof N))if(e="object"==typeof e&&e.h?e.g():String(e),Ya.test(e))e=new N(e,O);else{e=String(e);e=e.replace(/(%0A|%0D)/g,"");var g=e.match(Xa);e=g&&Wa.test(g[1])?new N(e,O):null}e=e||$a}g=void 0!==self.i;var k="strict-origin-when-cross-origin";
window.Request&&(k=(new Request("/")).referrerPolicy);k="unsafe-url"===k;if(g&&d.noreferrer){if(k)throw Error("Cannot use the noreferrer option on a page that sets a referrer-policy of `unsafe-url` in modern browsers!");d.noreferrer=!1}f=d.target||f.target;g=[];for(b in d)switch(b){case "width":case "height":case "top":case "left":g.push(b+"="+d[b]);break;case "target":case "noopener":case "noreferrer":break;default:g.push(b+"="+(d[b]?1:0))}b=g.join(",");if((J("iPhone")&&!J("iPod")&&!J("iPad")||J("iPad")||
J("iPod"))&&c.navigator&&c.navigator.standalone&&f&&"_self"!=f)b="A",g=document,b=String(b),"application/xhtml+xml"===g.contentType&&(b=b.toLowerCase()),g=b=g.createElement(b),e=e instanceof N?e:Za(e),g.href=P(e),b.setAttribute("target",f),d.noreferrer&&b.setAttribute("rel","noreferrer"),d=document.createEvent("MouseEvent"),d.initMouseEvent("click",!0,!0,c,1),b.dispatchEvent(d);else if(d.noreferrer){if(c=bb("",c,f,b),d=P(e),c){Qa&&-1!=d.indexOf(";")&&(d="'"+d.replace(/'/g,"%27")+"'");c.opener=null;
La.test(d)&&(-1!=d.indexOf("&")&&(d=d.replace(Fa,"&amp;")),-1!=d.indexOf("<")&&(d=d.replace(Ga,"&lt;")),-1!=d.indexOf(">")&&(d=d.replace(Ha,"&gt;")),-1!=d.indexOf('"')&&(d=d.replace(Ia,"&quot;")),-1!=d.indexOf("'")&&(d=d.replace(Ja,"&#39;")),-1!=d.indexOf("\x00")&&(d=d.replace(Ka,"&#0;")));d='<meta name="referrer" content="no-referrer"><meta http-equiv="refresh" content="0; url='+d+'">';if(void 0===L)if(b=null,(e=n.trustedTypes)&&e.createPolicy){try{b=e.createPolicy("goog#html",{createHTML:r,createScript:r,
createScriptURL:r})}catch(u){n.console&&n.console.error(u.message)}L=b}else L=b;d=(b=L)?b.createHTML(d):d;d=new Q(d,null,ab);(c=c.document)&&c.write&&(c.write(d instanceof Q&&d.constructor===Q?d.i:"type_error:SafeHtml"),c.close())}}else(c=bb(e,c,f,b))&&d.noopener&&(c.opener=null);a.g();break}}b=b.parentNode}};function wb(a,b,c,d){new vb(a,void 0===b?!1:b,void 0===c?!1:c,d)}var X=["DOCS_installLinkReferrerSanitizer"],Y=n;X[0]in Y||"undefined"==typeof Y.execScript||Y.execScript("var "+X[0]);
for(var Z;X.length&&(Z=X.shift());)X.length||void 0===wb?Y[Z]&&Y[Z]!==Object.prototype[Z]?Y=Y[Z]:Y=Y[Z]={}:Y[Z]=wb;}).call(this);
</script><script type="text/javascript" nonce="">DOCS_installLinkReferrerSanitizer( undefined,  true,  true , 'docs');</script></body></html>